# coding=utf-8

#加载配置文件
import  config
#加载函数库
from base_fun import base_fun;

import socket, select,time,random;
import threading;
import Queue;

#初始化基础函数
base_fun = base_fun(config.error_msg,db_len=config.db_hash_len);
index_job_list = {};

#config.debug = True;

#函数声明
#主贴处理函数
def add_index(index_obj,index_type,job_hash):
	while True:
		try:
			temp = index_job_list[index_type][job_hash].get(False);
			type = temp['type'];
			try:
				if type=="add":
					index_obj.add_index(temp['id'],temp['data']);
				elif type == "del":
					index_obj.del_index(temp['id'],temp['data']['field_num'],temp['data']['if_data']);
			except:
				row_data=[];
				for row in temp['data']:
					row_data.append(str(row));
				data_str = "-".join(row_data);
				log_msg = str(temp['id'])+"_"+data_str;
				log_type = index_type+'-index-'+type;
				log_level = 'error';
				base_fun.log(log_msg,log_type,log_level);
				#if config.debug:
				base_fun.show_except();
		except Queue.Empty:
			time.sleep(0.1);
			continue;


#声明进程
for key in config.search_index.keys():
	index_job_list[key]={};
	#获取参数变量
	new_obj_name = config.search_index[key]['obj'];
	sub_num = config.search_index[key]['thread_num'];
	base_dir = config.search_index[key]['dir'];
	#构造对象
	m = __import__('base_fun');
	new_obj = getattr(m,new_obj_name);
	obj = new_obj(base_fun,sub_num,base_dir);
	
	for i in range(sub_num):
		#初始化任务队列
		index_job_list[key][i]=Queue.Queue(0);
		#初始化进程
		t = threading.Thread(target=add_index,kwargs={'index_obj':obj,'index_type':key,'job_hash':i});
		t.start();


serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM);
serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1);
serversocket.bind(('0.0.0.0', config.make_index_port));
serversocket.listen(1);
serversocket.setblocking(0);

epoll = select.epoll();
epoll.register(serversocket.fileno(), select.EPOLLIN );

try:
	connections = {}; requests = {};
	while True:
		while True:
			events = epoll.poll(-1);
			for fileno, event in events:
				if fileno == serversocket.fileno():
					connection, address = serversocket.accept();
					connection.setblocking(0);
					epoll.register(connection.fileno(), select.EPOLLIN );
					connections[connection.fileno()] = connection;
					requests[connection.fileno()] = "";
				elif event & select.EPOLLIN:
					try:
						#接受头信息
						requests[fileno] = connections[fileno].recv(config.head_len);
						#关闭连接
						if len(requests[fileno]) ==0:
							raise Exception,"sanshi";
						temp_list = base_fun.pase_cmd_head(requests[fileno]);
						#取得命令
						cmd_no = temp_list[0];
						#内容长度
						body_len = temp_list[1];
						
						if config.debug:
							print "-"*12;
							print "cmd_no:"+str(cmd_no);
							print "body_len:"+str(body_len);
							print "-"*12;
						#内容长度解析错误处理
						if body_len>65535 or body_len<0:
							#发送返回信息
							connections[fileno].send(base_fun.build_cmd(-1000,base_fun.get_error_msg(-1000)));
							#触发异常
							raise Exception,"sanshi";
						#处理内容接收
						requests[fileno] +=connections[fileno].recv(body_len);
						while len(requests[fileno])<body_len:
							requests[fileno] +=connections[fileno].recv(1);
						body_info = base_fun.pase_body(requests[fileno],config.head_len,body_len);
						
						if config.debug:
							print "-"*12;
							print "body_info:";
							print body_info;
							print "-"*12;
						
						index_id = body_info['id'];
						index_data = body_info['data'];
						
						if config.debug:
							print "-"*12;
							print "index_id:"+str(index_id);
							print "index_data";
							print index_data;
							print "-"*12;
						
						index_type = config.index_cmd[cmd_no];
						#取得线程数量
						thread_num = config.search_index[index_type]['thread_num'];
						#取得索引类型
						make_type = config.search_index[index_type]['type'];
						
						#if config.debug:
						if True:
							print "-"*12;
							print index_type;
							for k, jobs in index_job_list[index_type].items():
								print time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()));
								print str(k)+":"+str(jobs.qsize());
								log_msg = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())) +"=="+str(k)+":"+str(jobs.qsize());
								log_type = index_type;
								log_level = 'error';
								base_fun.log(log_msg,log_type,log_level);
							print "-"*12;
						
						if cmd_no in config.index_add or cmd_no in config.index_del:
							#根据类确定hash
							hash_num = base_fun.get_hash_path(make_type,index_id,thread_num);
							if cmd_no in config.index_add:
								if config.debug:
									print "-"*12;
									print "add";
									print hash_num;
									print "-"*12;
								index_job_list[index_type][hash_num].put({'id':index_id,'data':index_data,'type':'add'});
							if cmd_no in config.index_del:
								if config.debug:
									print "-"*12;
									print "del";
									print hash_num;
									print "-"*12;
								index_job_list[index_type][hash_num].put({'id':index_id,'data':index_data,'type':'del'});
						else:
							print "not cmd";
							#发送返回信息
							connections[fileno].send(base_fun.build_cmd(-1001,base_fun.get_error_msg(-1001)));
							#触发异常
							#raise Exception,"sanshi";
						#返回循环
						epoll.modify(fileno, select.EPOLLIN);
					except:
						#关闭连接
						connections[fileno].shutdown(socket.SHUT_RDWR);
						epoll.unregister(fileno);
						connections[fileno].close();
						del connections[fileno];
						if config.debug:
							base_fun.show_except();

finally:
	epoll.unregister(serversocket.fileno());
	epoll.close();
	serversocket.close();